home *** CD-ROM | disk | FTP | other *** search
- /* TTY input line editing
- * Copyright 1991 Phil Karn, KA9Q
- * split screen by G. J. van der Grinten, PA0GRI
- * fixed split screen ^B and ^W functions - KO4KS
- */
- #include <stdio.h>
- #ifdef __TURBOC__
- #include <conio.h>
- #endif
- #include <ctype.h>
- #include "global.h"
- #include "config.h"
- #include "mbuf.h"
- #include "session.h"
- #include "tty.h"
- #include "socket.h"
-
- extern FILE *Rawterm;
- extern unsigned char SCREENwidth, SCREENlength;
- #ifdef TNOS_68K
- extern short UseCurses;
- #endif
-
- #define OFF 0
- #define ON 1
-
- #define LINESIZE 256
-
- #ifndef CTLR
- #define CTLR 18 /* reprint current line */
- #define CTLU 21 /* delete current line in total */
- #define CTLW 23 /* erase last word including preceding space */
- #define CTLZ 26 /* EOF char in dos */
- #define CTLB 02 /* use as F3 in dos but no editing */
- #endif
- #define DEL 0x7f
-
- #ifdef ALLSERV
-
- static int Lastsize = 1;
- static char Lastline[LINESIZE+1] = "\n";
-
- static void
- backspace ()
- {
- int x;
- x = wherex();
- #ifdef TNOS_68K
- if (!x && UseCurses)
- #else
- if (x == 1)
- #endif
- gotoxy(80, wherey() - 1);
- else {
- #ifdef TNOS_68K
- if (UseCurses)
- gotoxy(x - 1, wherey());
- else
- #endif
- cputs ("\b");
- }
- }
-
-
- static void
- space()
- {
- cputs(" ");
- }
-
-
- static void
- switchattr ()
- {
- #ifndef TNOS_68K
- struct text_info tr;
- unsigned char attr;
-
- gettextinfo(&tr);
- attr = ((tr.attribute & 0x0f) << 4) + ((tr.attribute & 0x70) >> 4);
- textattr (attr);
- #endif
- }
-
-
- static void
- tochatline(sp, gothere)
- struct session *sp;
- int gothere;
- {
- #ifndef TNOS_68K
- sp->tsavex = wherex();
- sp->tsavey = wherey();
- window(1,SCREENlength - 1,SCREENwidth,SCREENlength);
- switchattr ();
- if (gothere)
- gotoxy(sp->bsavex,sp->bsavey);
- #else
- if (UseCurses)
- sp->screen->win = sp->screen->splitwin;
- #endif
- }
-
-
- static void
- fromchatline(sp)
- struct session *sp;
- {
- #ifdef TNOS_68K
- if (UseCurses) {
- #endif
- cputs("_");
- backspace ();
- #ifdef TNOS_68K
- sp->screen->win = sp->screen->textwin;
- }
- #else
- sp->bsavex = wherex();
- sp->bsavey = wherey();
- window(1,1 + sp->screen->statline,SCREENwidth,SCREENlength - 2);
- switchattr ();
- gotoxy(sp->tsavex,sp->tsavey);
- #endif
- }
-
-
- void
- clrchatline (sp)
- struct session *sp;
- {
- tochatline (sp, 0);
- #ifdef TNOS_68K
- if (UseCurses) {
- werase (sp->screen->win);
- gotoxy (0, 0);
- }
- #else
- clrscr();
- #endif
- fromchatline (sp);
- }
-
-
- /* Accept characters from the incoming tty buffer and process them
- * (if in cooked mode) or just pass them directly (if in raw mode).
- *
- * Echoing (if enabled) is direct to the raw terminal. This requires
- * recording (if enabled) of locally typed info to be done by the session
- * itself so that edited output instead of raw input is recorded.
- * Control-W added by g1emm again.... for word delete.
- * Control-B/Function key 3 added by g1emm for line repeat.
- */
-
- struct mbuf *
- ttydriv(sp,c)
- struct session *sp;
- int c;
- {
- struct mbuf *bp;
- char *cp,*rp;
- int cnt;
-
- switch(sp->ttystate.edit){
- case OFF:
- bp = ambufw(1);
- *bp->data = c;
- bp->cnt = 1;
- if(sp->ttystate.echo){
- if(sp->split){
- tochatline (sp, 1);
- putch(c);
- fromchatline (sp);
- } else {
- #ifdef TNOS_68K
- putch(c);
- #else
- putc(c,Rawterm);
- #endif
- }
- }
- #ifdef TNOS_68K
- rflush ();
- #endif
- return bp;
- case ON:
- if(sp->ttystate.line == NULLBUF)
- sp->ttystate.line = ambufw(LINESIZE);
-
- bp = sp->ttystate.line;
- cp = bp->data + bp->cnt;
- /* Perform cooked-mode line editing */
- #ifdef notdef
- switch(c & 0x7f){
- #endif
- /* Allow for international character sets - WG7J */
- switch(c){
- case '\r': /* CR and LF both terminate the line */
- #ifdef TNOS_68K
- case '\l': /* CR and LF both terminate the line */
- #else
- case '\n':
- #endif
- if(sp->ttystate.crnl)
- *cp = '\n';
- else
- *cp = c;
- if(sp->ttystate.echo){
- if(sp->split){
- #ifdef TNOS_68K
- if (UseCurses) {
- #endif
- highvideo();
- rp = bp->data;
- while(rp < cp)
- putch(*rp++);
- lowvideo();
- clreol();
- #ifdef TNOS_68K
- }
- #endif
- cputs(Eol);
- clreol();
- clrchatline(sp);
- } else {
- #ifdef TNOS_68K
- cputs(Eol);
- #else
- fputs(Eol,Rawterm);
- #endif
- }
- }
- bp->cnt += 1;
- sp->ttystate.line = NULLBUF;
- Lastsize = bp->cnt;
- memcpy(Lastline, bp->data, Lastsize);
- return bp;
- case DEL:
- case '\b': /* Character delete */
- if(bp->cnt != 0){
- bp->cnt--;
- if(sp->ttystate.echo){
- if(sp->split){
- tochatline (sp, 1);
- space ();
- backspace ();
- backspace ();
- fromchatline (sp);
- } else {
- backspace();
- space ();
- backspace ();
- }
- }
- }
- break;
- case CTLR: /* print line buffer */
- if(sp->ttystate.echo){
- if(sp->split) {
- tochatline (sp, 1);
- #ifdef TNOS_68K
- if (UseCurses)
- werase (sp->screen->win);
- #else
- clrscr();
- #endif
- rp = bp->data;
- while (rp < cp)
- putch(*rp++) ;
- fromchatline (sp);
- } else {
- #ifdef TNOS_68K
- cnt = bp->cnt;
- while(cnt != 0){
- cnt--;
- if(sp->ttystate.echo) {
- backspace ();
- space ();
- backspace ();
- }
- }
- #else
- fprintf(Rawterm,"^R%s",Eol) ;
- #endif
- rp = bp->data;
- while (rp < cp)
- #ifdef TNOS_68K
- putch(*rp++) ;
- #else
- putc(*rp++,Rawterm) ;
- #endif
- }
- }
- break ;
- case CTLU: /* Line kill */
- if(sp->split) {
- clrchatline (sp);
- bp->cnt = 0;
- } else {
- while(bp->cnt != 0){
- bp->cnt--;
- if(sp->ttystate.echo) {
- backspace ();
- space ();
- backspace ();
- }
- }
- }
- break;
- case CTLB: /* Use last line to finish current */
- if(!sp->split) {
- cnt = bp->cnt; /* save count so far */
-
- while(bp->cnt != 0){
- bp->cnt--;
- if(sp->ttystate.echo) {
- backspace ();
- space ();
- backspace ();
- }
- }
- bp->cnt = cnt;
- }
-
- if(bp->cnt < (Lastsize-1)){
- memcpy(bp->data+bp->cnt, &Lastline[bp->cnt], (Lastsize-1) - bp->cnt);
- bp->cnt = Lastsize-1;
- }
-
- *(bp->data + bp->cnt) = '\0'; /* make it a string */
- if(sp->ttystate.echo)
- if(sp->split) {
- tochatline (sp, 1); /* was 0 */
- #ifdef TNOS_68K
- if (UseCurses)
- werase (sp->screen->win);
- #else
- clrscr();
- #endif
- cputs (bp->data);
- fromchatline (sp);
- } else
- #ifdef TNOS_68K
- cputs (bp->data);
- #else
- fputs(bp->data, Rawterm); /* repaint line */
- #endif
- break ;
- case CTLW: /* erase word */
- if(sp->split)
- if (sp->ttystate.echo) {
- tochatline (sp, 1);
- space ();
- backspace ();
- }
- cnt = 0 ; /* we haven't seen a printable char yet */
- while(bp->cnt != 0){
- *(bp->data + bp->cnt--) = '\n';
- if(sp->ttystate.echo)
- if (sp->split) {
- backspace ();
- space ();
- backspace ();
- }
- else {
- backspace ();
- space ();
- backspace ();
- }
- if (isspace((int)*(bp->data + bp->cnt))) {
- if (cnt)
- break ;
- } else {
- cnt = 1 ;
- }
- }
- if(sp->split && sp->ttystate.echo)
- fromchatline (sp);
- break ;
- case UPARROW: /* Recall previous command - WG7J */
- case DNARROW: /* Recall next command - WG7J */
- if(Histry) {
- /* Blank out what's already there */
- while(bp->cnt != 0 && sp->ttystate.echo){
- bp->cnt--;
- cputs("\b \b");
- }
- if (c == DNARROW)
- /* Adjust history */
- Histry = Histry->next;
- /* Recall last command */
- strcpy(bp->data,Histry->cmd);
- bp->cnt = strlen(Histry->cmd);
- if (c == UPARROW)
- /* Adjust history */
- Histry = Histry->prev;
- /* repaint line */
- if(sp->ttystate.echo)
- cputs(bp->data);
- }
- break ;
- default: /* Ordinary character */
- *cp = c;
- bp->cnt++;
-
- /* ^Z apparently hangs the terminal emulators under
- * DoubleDos and Desqview. I REALLY HATE having to patch
- * around other people's bugs like this!!!
- */
- if(sp->ttystate.echo &&
- #ifndef AMIGA
- c != CTLZ &&
- #endif
- bp->cnt < LINESIZE-1){
- if(sp->split) {
- tochatline (sp, 1);
- putch(c);
- fromchatline (sp);
- } else {
- #ifdef TNOS_68K
- putch(c);
- #else
- putc(c,Rawterm);
- #endif
- }
-
- } else if(bp->cnt >= LINESIZE-1){
- #ifdef TNOS_68K
- putch('\007'); /* Beep */
- #else
- putc('\007',Rawterm); /* Beep */
- #endif
- bp->cnt--;
- }
- break;
- }
- break;
- }
- #ifdef TNOS_68K
- rflush ();
- #endif
- return NULLBUF;
- }
-
- #else
-
-
- /* Accept characters from the incoming tty buffer and process them
- * (if in cooked mode) or just pass them directly (if in raw mode).
- *
- * Echoing (if enabled) is direct to the raw terminal. This requires
- * recording (if enabled) of locally typed info to be done by the session
- * itself so that edited output instead of raw input is recorded.
- */
- struct mbuf *
- ttydriv(sp,c)
- struct session *sp;
- int c;
- {
- struct mbuf *bp;
- char *cp,*rp;
-
- switch(sp->ttystate.edit){
- case OFF:
- bp = ambufw(1);
- *bp->data = c;
- bp->cnt = 1;
- if(sp->ttystate.echo)
- putc(c,Rawterm);
-
- return bp;
- case ON:
- if(sp->ttystate.line == NULLBUF)
- sp->ttystate.line = ambufw(LINESIZE);
-
- bp = sp->ttystate.line;
- cp = bp->data + bp->cnt;
- /* Perform cooked-mode line editing */
- switch(c & 0x7f){
- case '\r': /* CR and LF both terminate the line */
- case '\n':
- if(sp->ttystate.crnl)
- *cp = '\n';
- else
- *cp = c;
- if(sp->ttystate.echo)
- fputs(Eol,Rawterm);
-
- bp->cnt += 1;
- sp->ttystate.line = NULLBUF;
- return bp;
- case DEL:
- case '\b': /* Character delete */
- if(bp->cnt != 0){
- bp->cnt--;
- if(sp->ttystate.echo)
- fputs("\b \b",Rawterm);
- }
- break;
- case CTLR: /* print line buffer */
- if(sp->ttystate.echo){
- fprintf(Rawterm,"^R%s",Eol) ;
- rp = bp->data;
- while (rp < cp)
- putc(*rp++,Rawterm) ;
- }
- break ;
- case CTLU: /* Line kill */
- while(bp->cnt != 0){
- bp->cnt--;
- if(sp->ttystate.echo){
- fputs("\b \b",Rawterm);
- }
- }
- break;
- case UPARROW: /* Recall previous command - WG7J */
- case DNARROW: /* Recall next command - WG7J */
- if(Histry) {
- /* Blank out what's already there */
- while(bp->cnt != 0 && sp->ttystate.echo){
- bp->cnt--;
- cputs("\b \b");
- }
- if (c == DNARROW)
- /* Adjust history */
- Histry = Histry->next;
- /* Recall last command */
- strcpy(bp->data,Histry->cmd);
- bp->cnt = strlen(Histry->cmd);
- if (c == UPARROW)
- /* Adjust history */
- Histry = Histry->prev;
- /* repaint line */
- if(sp->ttystate.echo)
- cputs(bp->data);
- }
- break ;
- default: /* Ordinary character */
- *cp = c;
- bp->cnt++;
-
- /* ^Z apparently hangs the terminal emulators under
- * DoubleDos and Desqview. I REALLY HATE having to patch
- * around other people's bugs like this!!!
- */
- if(sp->ttystate.echo &&
- #ifndef AMIGA
- c != CTLZ &&
- #endif
- bp->cnt < LINESIZE-1){
- putc(c,Rawterm);
-
- } else if(bp->cnt >= LINESIZE-1){
- putc('\007',Rawterm); /* Beep */
- bp->cnt--;
- }
- break;
- }
- break;
- }
- return NULLBUF;
- }
-
- #endif /*ALLSERV*/
-